Next: SMIE Lexer, Previous: Operator Precedence Grammars, Up: SMIE [Contents][Index]
The usual way to define the SMIE grammar of a language is by defining a new global variable that holds the precedence table by giving a set of BNF rules. For example, the grammar definition for a small Pascal-like language could look like:
(require 'smie) (defvar sample-smie-grammar (smie-prec2->grammar (smie-bnf->prec2
'((id)
(inst ("begin" insts "end")
("if" exp "then" inst "else" inst)
(id ":=" exp)
(exp))
(insts (insts ";" insts) (inst))
(exp (exp "+" exp)
(exp "*" exp)
("(" exps ")"))
(exps (exps "," exps) (exp)))
'((assoc ";"))
'((assoc ","))
'((assoc "+") (assoc "*")))))
A few things to note:
begin ... end blocks to appear anywhere
anyway.id has no right hand
side: this does not mean that it can match only the empty
string, since as mentioned any sequence of sexps can appear
anywhere anyway.";" as a statement separator instead,
which SMIE can handle very well."," and
";" above) are best defined with BNF rules such as
(foo (foo "separator" foo) ...) which generate
precedence conflicts which are then resolved by giving them an
explicit (assoc "separator").("(" exps ")") rule was not needed to pair
up parens, since SMIE will pair up any characters that are
marked as having paren syntax in the syntax table. What this
rule does instead (together with the definition of
exps) is to make it clear that ","
should not appear outside of parentheses.left or right, it is usually
preferable to mark operators as associative, using
assoc. For that reason "+" and
"*" are defined above as assoc,
although the language defines them formally as left
associative.Next: SMIE Lexer, Previous: Operator Precedence Grammars, Up: SMIE [Contents][Index]